from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from app01.models import DeviceData
import logging

logger = logging.getLogger(__name__)


@receiver(post_save, sender=DeviceData)
def handle_device_data_update(sender, instance, **kwargs):
    """
    当DeviceData数据变更时触发实时推送
    执行逻辑：
    1. 检查版本号是否变化
    2. 更新缓存版本
    3. 推送变更到WebSocket组
    """

    """确保每条数据变更都触发推送"""
    try:
        # 1. 获取组名和缓存键
        group_name = f"device_{instance.deviceName}"
        version_key = f"{group_name}_version"

        # 2. 原子化版本更新
        with cache.lock(f"{group_name}_lock", timeout=10):
            last_version = cache.get(version_key, 0)
            if instance.version > last_version:
                cache.set(version_key, instance.version)

                # 3. 准备推送数据
                update_data = {
                    'type': 'realtime_update',
                    'version': instance.version,
                    'data': instance.get_parsed_items()
                }

                # 5. 发送到通道层
                channel_layer = get_channel_layer()
                async_to_sync(channel_layer.group_send)(
                    group_name,
                    {
                        "type": "device.update",  # 必须匹配消费者的方法名
                        "data": update_data
                    }
                )

    except Exception as e:
        logger.error(f"信号处理失败: {e}", exc_info=True)

